#include "Win32Timer.h"

using namespace System;

Win32Timer::Win32Timer(void)
{
	mFrequency = 0;;
	mTicksPerMs = 0;
	mStartTime = 0;
	mFrameTime = 0;
	mPrevTime = 0;
}


Win32Timer::~Win32Timer(void)
{
	if(mCanReadCpu)
	{
		PdhCloseQuery(mQueryHandle);
	}
}

bool Win32Timer::Initialize()
{
	// Check to see if this system supports high performance timers.
	QueryPerformanceFrequency((LARGE_INTEGER*)&mFrequency);
	if(mFrequency == 0)
	{
		return false;
	}

	// Find out how many times the frequency counter ticks every millisecond.
	mTicksPerMs = (float)(mFrequency / 1000);

	QueryPerformanceCounter((LARGE_INTEGER*)&mStartTime);

	/*		CPU			*/
	PDH_STATUS status;
	// Initialize the flag indicating whether this object can read the system cpu usage or not.
	mCanReadCpu = true;

	// Create a query object to poll cpu usage.
	status = PdhOpenQuery(NULL, 0, &mQueryHandle);
	if(status != ERROR_SUCCESS)
	{
		mCanReadCpu = false;
	}

	// Set query object to poll all cpus in the system.
	status = PdhAddCounter(mQueryHandle, TEXT("\\Processor(_Total)\\% processor time"), 0, &mCounterHandle);
	if(status != ERROR_SUCCESS)
	{
		mCanReadCpu = false;
	}

	mLastSampleTime = GetTickCount(); 
	mCpuUsage = 0;

	/*		FPS		*/
	mFps = 0;
	mCount = 0;
	mFPSStartTime = timeGetTime();

	return true;
}

void Win32Timer::Update()
{
	QueryPerformanceCounter((LARGE_INTEGER*)& mCurrentTime);

	float timeDifference = (float)(mCurrentTime - mPrevTime);
	mPrevTime = mCurrentTime;

	mFrameTime = (timeDifference / mTicksPerMs) / 1000;

	//FPS
	mCount++;
	if(timeGetTime() >= (mFPSStartTime + 1000))
	{
		mFps = mCount;
		mCount = 0;

		mFPSStartTime = timeGetTime();
	}

	//CPU
	if(mCanReadCpu)
	{
		if((mLastSampleTime + 1000) < GetTickCount())
		{
			mLastSampleTime = GetTickCount(); 

			PdhCollectQueryData(mQueryHandle);

        	PDH_FMT_COUNTERVALUE value;
			PdhGetFormattedCounterValue(mCounterHandle, PDH_FMT_LONG, NULL, &value);

			mCpuUsage = value.longValue;
		}
	}

	return;
}

float Win32Timer::GetElapsedTime()
{
	Update();
	return mFrameTime;
}

float Win32Timer::GetTime()
{
	return (float)(mCurrentTime/1000 - mStartTime/1000) / 1000;
}

int Win32Timer::GetFPS()
{
	return mFps;
}

int Win32Timer::GetCpuPercentage()
{
	int usage;

	if(mCanReadCpu)
	{
		usage = (int)mCpuUsage;
	}
	else
	{
		usage = 0;
	}

	return usage;
}